# -*- coding: utf-8 -*-
import json
import requests
from dingtalk import AppKeyClient
from django.conf import settings

from account.models import OrgStructure, User, OrgLabel
from config.settings.base import logger

from common import DINGTALK_CORP_ID, DINGTALK_APP_KEY, DINGTALK_APP_SECRET, encodingAesKey, token


class DingClient(AppKeyClient):
    def __init__(self):
        super(DingClient, self).__init__(
            DINGTALK_CORP_ID, DINGTALK_APP_KEY,
            DINGTALK_APP_SECRET, token=token,
            aes_key=encodingAesKey)

    def get_department_ids(self, proced=set(), parent_id=None):

        ret = set()
        if parent_id is None:
            scopes = self.user.auth_scopes()
            parent_id = scopes.get('auth_org_scopes', {}).get('authed_dept', [])

        if isinstance(parent_id, (list, tuple)):
            for pid in parent_id:
                ret.update(self.get_department_ids(proced, pid))
            return ret

        if parent_id in proced:
            return ret
        ret.add(parent_id)
        dept_info = self.department.get(parent_id)
        org_name = dept_info['name']
        data = {
            'name': org_name,
        }
        parent_qs = OrgStructure.objects.filter(department_id=dept_info.get('parentid', 0), )
        if parent_qs.exists():
            data['parent'] = parent_qs.first()
        org, _ = OrgStructure.objects.get_or_create(
            department_id=dept_info['id'],
            defaults=data
        )
        ids = self.department.list_ids(parent_id)
        proced.add(parent_id)
        ret.update(set(ids))
        for _id in ids:
            ret.update(self.get_department_ids(proced, _id))
        return ret

    def set_corp_user(self, user_info, department_id):
        org = OrgStructure.objects.get(department_id=department_id)
        user, created = User.objects.update_or_create(
            username=user_info.get('userid'),
            defaults={
                'nickname': user_info.get('name'),
                'mobile': user_info.get('mobile', ''),
                # 'is_staff': user_info.get('isAdmin'),  # todo 后台用户身份暂不与钉钉管理员配置挂钩
                'avatar': user_info.get('avatar'),
                'is_active': user_info.get('active')
            }
        )
        user.set_password('666666')
        user.org.add(org)
        user.save()

    def sync_user(self, department_id):
        offset = 0
        while True:
            users = self.user.list(department_id)
            for user in users.get('userlist', []):
                offset += 1
                self.set_corp_user(user, department_id)
            if not users.get('hasMore', False):
                return

    def sync_org_manager(self, department_id):
        """
        同步机构负责人
        :param department_id:
        :return:
        """
        dept_info = self.department.get(department_id)
        org_qs = OrgStructure.objects.filter(department_id=dept_info['id'],)
        if org_qs.exists():
            org = org_qs.first()
            manager_ids = dept_info.get('deptManagerUseridList', '')
            if manager_ids:
                manager_ids = manager_ids.split('|')
                manager_qs = User.objects.filter(username__in=manager_ids)
                for manager in manager_qs:
                    org.managers.add(manager)

    def sync_label(self):
        offset = 0
        while True:
            res = requests.post(
                'https://oapi.dingtalk.com/topapi/role/list?access_token={}'.format(
                    self.access_token), data={'offset': offset})
            content = json.loads(res.content)
            if content.get('errcode') == 0:
                label_info = content.get('result')
                for group in label_info.get('list'):
                    offset += 1
                    labels = group.get('roles')
                    for label in labels:
                        label_obj, created = OrgLabel.objects.get_or_create(
                            label_id=label.get('id'),
                            is_active=True,
                            defaults={
                                'name': label.get('name'),
                            },
                        )
                        self.sync_label_user(label_obj)
                if not label_info.get('hasMore', False):
                    return
            else:
                logger.info(content)
                return

    def sync_label_user(self, label):
        """
        获取角色下员工列表
        :param label:
        :return:
        """
        user_offset = 0
        while True:
            response = requests.post(
                'https://oapi.dingtalk.com/topapi/role/simplelist?access_token={}'.format(
                    self.access_token),
                data={'role_id': label.label_id,
                      'offset': user_offset})
            user_content = json.loads(response.content)
            if user_content.get('errcode') == 0:
                user_info = user_content.get('result')
                for user in user_info.get('list'):
                    user_offset += 1
                    user_id = user.get('userid')
                    user_obj = User.objects.get(username=user_id)
                    label.user.add(user_obj)
                if not user_info.get('hasMore', False):
                    return

    def sync_corp(self):
        """
        数据同步
        :return:
        """
        department_ids = self.get_department_ids()
        for department_id in department_ids:
            self.sync_user(department_id)
            self.sync_org_manager(department_id)
        self.sync_label()





